import { Timer } from '../timer'

/**
 * 自动过期的储存对象
 */
export class ExpireStore<T extends Object> {
  /**
   * 计时器
   */
  private timer = new Timer()

  /**
   * 存储数据
   */
  private dataMap = new WeakMap<T, ExpireStoreData>()

  constructor(private option: ExpireStoreOption<T>) {}

  /**
   * 清空
   */
  clear() {
    this.timer.clear()
  }

  /**
   * 更新数据项
   * @param item
   */
  update(item: T) {
    const timeout = this.timer.setTimeout(() => {
      if (this.remove(item)) {
        this.option.onExpire(item)
      }
    }, this.option.expire)

    const data = this.dataMap.get(item)
    if (data) {
      this.timer.clearTimeout(data.timeout)
      data.timeout = timeout
    } else {
      this.dataMap.set(item, { timeout })
    }
  }

  /**
   * 删除数据项
   * @param item
   */
  remove(item: T) {
    const data = this.dataMap.get(item)
    if (data) {
      this.timer.clearTimeout(data.timeout)
      this.dataMap.delete(item)
      return true
    }
    return false
  }

  /**
   * 是否包含数据项
   * @param item
   * @returns
   */
  has(item: T) {
    return this.dataMap.has(item)
  }
}

export interface ExpireStoreOption<T extends Object> {
  // 过期时间，单位：ms
  expire: number
  // 数据项过期时，只在时间过期时触发
  onExpire: (item: T) => void
}

export interface ExpireStoreData {
  timeout: NodeJS.Timeout
}
